import LayerBase from "./LayerBase.js";

/**
 * 图元图层
 * 图元的容器，提供对多个图元的统一管理
 * @class GraphicLayer
 * @extends LayerBase
 */
class GraphicLayer extends LayerBase {

  /**
   * 构造函数
   * @param {Object} options 配置选项
   * @param {Cesium.Viewer} options.viewer 场景viewer对象
   * @param {String} [options.id] 图层id，必须唯一，默认自动创建
   * @param {String} [options.name] 图层名称
   * @param {String} [options.remarks] 图层备注
   * @param {Boolean} [options.show=true] 图层是否显示
   * @param {Boolean} [options.selectedEnable=true] 图层是否可以选中图元
   * @param {Boolean} [options.hasEdit=true] 图层是否启用编辑
   */
  constructor(options) {
    // 合并默认选项
    const defaultOptions = {
      selectedEnable: true,
      hasEdit: true,
    };
    const mergedOptions = Object.assign({}, defaultOptions, options);

    super(mergedOptions);

    // 初始化图元相关属性
    this._graphics = []; // 图元集合
    this._selectedGraphic = null; // 当前选中的图元
    this._editGraphic = null; // 当前编辑的图元
    this._selectedEnable = !!mergedOptions.selectedEnable;
    this._hasEdit = !!mergedOptions.hasEdit;

    // 初始化DOM容器
    this._initDomContainer();
    
    // 确保初始化后同步显示状态
    if (this._domContainer) {
      this._domContainer.style.display = this._show ? 'block' : 'none';
    }

    // 绑定事件处理器
    this._bindEvents();
  }

  /**
   * 获取图层当前编辑的图元
   * @readonly
   * @type {BaseGraphic}
   */
  get editGraphic() {
    return this._editGraphic;
  }

  /**
   * 获取图层中的图元集合
   * @readonly
   * @type {Array}
   */
  get graphics() {
    return this._graphics;
  }

  /**
   * 获取或设置图层是否启用编辑
   * @type {Boolean}
   */
  get hasEdit() {
    return this._hasEdit;
  }

  set hasEdit(value) {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    this._hasEdit = !!value;

    // 如果关闭编辑，结束当前编辑状态
    if (!this._hasEdit && this._editGraphic) {
      this.endDraw();
    }
  }

  /**
   * 获取或设置图层是否可以选中图元
   * @type {Boolean}
   */
  get selectedEnable() {
    return this._selectedEnable;
  }

  set selectedEnable(value) {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    this._selectedEnable = !!value;

    // 如果关闭选中，取消当前选中状态
    if (!this._selectedEnable && this._selectedGraphic) {
      this._selectedGraphic.selected = false;
      this._selectedGraphic = null;
    }
  }

  /**
   * 获取图层当前选中的图元
   * @readonly
   * @type {BaseGraphic}
   */
  get selectedGraphic() {
    return this._selectedGraphic;
  }

  /**
   * 添加图元到图层中
   * @param {Object} graphic 要添加的图元
   */
  add(graphic) {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    if (!graphic || !graphic.id) {
      throw new Error("Invalid graphic: must have an id");
    }

    console.log(`添加图元到图层: ${graphic.id}`);

    // 检查是否已存在相同id的图元
    const existingGraphic = this.getById(graphic.id);
    if (existingGraphic) {
      // 重设id以避免冲突
      const newId = `${graphic.id}_${Date.now()}`;
      console.warn(`图元ID ${graphic.id} 已存在，新ID: ${newId}`);
      graphic.id = newId;
    }

    // 添加到集合中
    this._graphics.push(graphic);

    // 设置图元的图层引用
    graphic.layer = this;

    // 设置图元的显示状态
    graphic.show = this._show;

    // 确保DOM容器存在
    if (!this._domContainer) {
      console.warn("图层DOM容器不存在，尝试重新初始化");
      this._initDomContainer();
    }

    // 将图元的DOM元素添加到容器中
    if (graphic.domEle && this._domContainer) {
      // 确保DOM元素没有其他父节点
      if (graphic.domEle.parentNode) {
        console.warn(`图元DOM元素已有父节点，先移除`);
        try {
          graphic.domEle.parentNode.removeChild(graphic.domEle);
        } catch (e) {
          console.error("移除DOM元素失败:", e);
        }
      }

      try {
        this._domContainer.appendChild(graphic.domEle);
        console.log(`图元DOM元素成功添加到图层容器`);
        console.log(`DOM元素ID: ${graphic.domEle.id}`);
        console.log(`DOM元素样式: ${graphic.domEle.style.cssText}`);
        // 更新图元的位置
        graphic.updatePosition(this._viewer.scene);
      } catch (e) {
        console.error("添加DOM元素到图层容器失败:", e);
      }
    } else {
      console.warn(
        `无法添加图元DOM元素，graphic.domEle: ${!!graphic.domEle}, domContainer: ${!!this
          ._domContainer}`
      );
    }

    // 触发添加事件
    this.fire("add", { graphic });

    return graphic;
  }

  /**
   * 从指定的json数据中追加图元
   * 已有数据不会被清空，如果图元id重复，将重设图元的id
   * @param {Object} json json数据，必须是toGeoJson()转出的数据
   * @returns {Promise}
   */
  async appendFromGeoJson(json) {
    if (this.isDestroyed()) {
      return Promise.reject(new Error("Object has been destroyed"));
    }

    try {
      // 处理features数组中的每个图元数据
      if (json.features && Array.isArray(json.features)) {
        for (const feature of json.features) {
          // 这里需要根据feature的属性创建对应的图元实例
          // 由于缺少具体的图元类型定义，这里仅做示例
          // 实际使用时需要根据项目中的图元类型进行处理
          console.warn(
            "appendFromGeoJson: 需要根据实际图元类型实现图元创建逻辑"
          );
        }
      }

      this.fire("appendComplete");
      return Promise.resolve();
    } catch (error) {
      this.fire("appendError", error);
      return Promise.reject(error);
    }
  }

  /**
   * 从本地数据追加图元
   * 已有数据不会被清空，如果图元id重复，将重设图元的id
   * 必须是downloadToLocalFile()转出的数据
   * @returns {Promise}
   */
  async appendFromLocalFile() {
    if (this.isDestroyed()) {
      return Promise.reject(new Error("Object has been destroyed"));
    }

    return new Promise((resolve, reject) => {
      const input = document.createElement("input");
      input.type = "file";
      input.accept = "application/json";

      input.onchange = async (event) => {
        const file = event.target.files[0];
        if (!file) {
          reject(new Error("No file selected"));
          return;
        }

        const reader = new FileReader();
        reader.onload = async (e) => {
          try {
            const json = JSON.parse(e.target.result);
            await this.appendFromGeoJson(json);
            resolve();
          } catch (error) {
            this.fire("appendError", error);
            reject(error);
          }
        };

        reader.onerror = (error) => {
          this.fire("appendError", error);
          reject(error);
        };

        reader.readAsText(file);
      };

      input.click();
    });
  }

  /**
   * 从指定的url追加图元
   * 已有数据不会被清空，如果图元id重复，将重设图元的id
   * @param {String} url 地址，存放的必须是toGeoJson()转出的数据
   * @returns {Promise}
   */
  async appendFromUrl(url) {
    if (this.isDestroyed()) {
      return Promise.reject(new Error("Object has been destroyed"));
    }

    try {
      const response = await fetch(url);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const json = await response.json();
      await this.appendFromGeoJson(json);
      return Promise.resolve();
    } catch (error) {
      this.fire("appendError", error);
      return Promise.reject(error);
    }
  }

  /**
   * 销毁对象
   * @override
   * @inheritDoc
   */
  destroy() {
    if (this.isDestroyed()) {
      return;
    }

    // 移除所有图元
    this.removeAll();

    // 移除事件监听器
    if (this._viewer && this._viewer.scene && this._scenePostRenderHandler) {
      this._viewer.scene.postRender.removeEventListener(
        this._scenePostRenderHandler
      );
    }

    // 移除屏幕事件处理器
    if (this._screenSpaceEventHandler) {
      this._screenSpaceEventHandler.destroy();
      this._screenSpaceEventHandler = null;
    }

    // 移除DOM容器
    if (this._domContainer && this._domContainer.parentNode) {
      this._domContainer.parentNode.removeChild(this._domContainer);
    }

    // 清空引用
    this._graphics = null;
    this._selectedGraphic = null;
    this._editGraphic = null;
    this._selectedEnable = null;
    this._hasEdit = null;
    this._domContainer = null;
    this._scenePostRenderHandler = null;

    // 调用父类的destroy方法
    super.destroy();
  }

  /**
   * 手动结束绘制图元
   */
  endDraw() {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    if (this._editGraphic) {
      this._editGraphic.endEdit();
      this._editGraphic = null;
      this.fire("endDraw");
    }
  }

  /**
   * 定位到图元
   * @param {BaseGraphic} graphic 定位的图元，如果未指定将定位到所有图元
   * @param {Object} flyOpts 定位参数,见Cesium.Camera.flyToBoundingSphere()
   */
  flyTo(graphic, flyOpts) {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    if (!this._viewer || !this._viewer.camera) {
      throw new Error("Viewer camera not available");
    }

    // 默认飞行选项
    const defaultFlyOpts = {
      duration: 1.5,
      offset: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-90),
        roll: 0,
      },
    };
    const options = Object.assign({}, defaultFlyOpts, flyOpts);

    if (graphic) {
      // 定位到单个图元
      if (graphic.getBoundingSphere) {
        const boundingSphere = graphic.getBoundingSphere();
        if (boundingSphere) {
          this._viewer.camera.flyToBoundingSphere(boundingSphere, options);
        }
      }
    } else if (this._graphics.length > 0) {
      // 定位到所有图元
      const positions = [];

      this._graphics.forEach((g) => {
        if (g.positions && Array.isArray(g.positions)) {
          positions.push(...g.positions);
        }
      });

      if (positions.length > 0) {
        const boundingSphere = Cesium.BoundingSphere.fromPoints(positions);
        this._viewer.camera.flyToBoundingSphere(boundingSphere, options);
      }
    }
  }

  /**
   * 根据id查找图元
   * @param {String} id 图元id
   * @returns {BaseGraphic} 查找到的图元，不存在则返回null
   */
  getById(id) {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    return this._graphics.find((graphic) => graphic.id === id) || null;
  }

  /**
   * 从图层中移除图元
   * @param {Object} graphic 要移除的图元
   */
  remove(graphic) {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    if (!graphic) {
      return false;
    }

    const index = this._graphics.indexOf(graphic);
    if (index !== -1) {
      // 如果是选中的图元，取消选中
      if (this._selectedGraphic === graphic) {
        this._selectedGraphic = null;
      }

      // 如果是编辑中的图元，结束编辑
      if (this._editGraphic === graphic) {
        this._editGraphic = null;
      }

      // 移除图元
      this._graphics.splice(index, 1);

      // 清理图元引用
      if (graphic.destroy) {
        graphic.destroy();
      }

      // 触发移除事件
      this.fire("remove", { graphic });

      return true;
    }

    return false;
  }

  /**
   * 移除所有图元
   */
  removeAll() {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    // 触发移除所有事件
    this.fire("removeAll", { graphics: [...this._graphics] });

    // 销毁所有图元
    this._graphics.forEach((graphic) => {
      if (graphic.destroy) {
        graphic.destroy();
      }
    });

    // 清空集合并重置状态
    this._graphics.length = 0;
    this._selectedGraphic = null;
    this._editGraphic = null;
  }

  /**
   * 根据图元id从图层中移除图元
   * @param {string} id 要移除的图元id
   */
  removeById(id) {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    const graphic = this.getById(id);
    return this.remove(graphic);
  }

  /**
   * 开始绘制图元
   * @param {Object} options 绘制图元参数
   * @param {GraphicClassType} [options.graphicClassType] 图元类型
   * @param {Object} [options.style] 图元样式
   * @param {Object} [options.userData] 用户数据
   */
  startDraw(options) {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    if (!this._hasEdit) {
      throw new Error("Editing is not enabled for this layer");
    }

    // 结束当前可能的编辑状态
    this.endDraw();

    // 这里需要根据graphicClassType创建对应的图元实例
    // 由于缺少具体的图元类型定义，这里仅做示例
    // 实际使用时需要根据项目中的图元类型进行处理
    console.warn("startDraw: 需要根据实际图元类型实现图元创建和绘制逻辑");

    // 触发开始绘制事件
    this.fire("startDraw", options);
  }

  /**
   * 转换成json
   * @override
   * @returns {Object} Geojson数据
   */
  toGeoJson() {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    const geojson = super.toGeoJson();

    // 添加图元数据到features数组
    geojson.features = [];

    this._graphics.forEach((graphic) => {
      if (graphic.toGeoJson) {
        const feature = graphic.toGeoJson();
        if (feature) {
          geojson.features.push(feature);
        }
      }
    });

    return geojson;
  }

   /**
   * 获取图层是否显示
   * @type {Boolean}
   */
  get show() {
    return super.show;
  }
  /**
   * 重写show属性的setter，同步更新所有图元的显示状态
   */
  set show(value) {
    if (this.isDestroyed()) {
      throw new Error("Object has been destroyed");
    }

    const showValue = !!value;
    super.show = showValue;

    // 显示或隐藏DOM容器
    if (this._domContainer) {
      this._domContainer.style.display = showValue ? "block" : "none";
    }

    // 同步更新所有图元的显示状态
    this._graphics.forEach((graphic) => {
      graphic.show = showValue;
    });
  }

  /**
   * 初始化DOM容器
   * @private
   */
  _initDomContainer() {
    if (!this._viewer || !this._viewer.container) {
      console.warn(
        "Viewer container not available, cannot initialize DOM container"
      );
      return;
    }

    // 创建DOM容器
    this._domContainer = document.createElement("div");
    // 使用CSS类替代内联样式，提高可维护性
    this._domContainer.className = "cesium-extensions-graphic-layer";

    // 将容器添加到viewer容器中
    this._viewer.container.appendChild(this._domContainer);
  }

  /**
   * 更新所有图元的位置
   * @private
   */
  _updateGraphicsPositions() {
    if (!this._viewer || !this._viewer.scene) return;

    this._graphics.forEach((graphic) => {
      if (graphic.updatePosition) {
        graphic.updatePosition(this._viewer.scene);
      }
    });
  }

  /**
   * 绑定事件处理器
   * @private
   */
  _bindEvents() {
    if (!this._viewer) return;

    // 绑定场景渲染事件，用于更新图元位置
    this._scenePostRenderHandler = this._updateGraphicsPositions.bind(this);
    this._viewer.scene.postRender.addEventListener(
      this._scenePostRenderHandler
    );

    // 绑定点击事件，用于图元选中
    this._screenSpaceEventHandler = new Cesium.ScreenSpaceEventHandler(
      this._viewer.canvas
    );
    this._screenSpaceEventHandler.setInputAction((event) => {
      if (!this._selectedEnable) return;

      // 这里可以实现图元选中逻辑
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  }
}

export default GraphicLayer;
